
#include "NNClassifier.h"




NNClassifier::NNClassifier(int dim)
{
	isInitialized = false;
	isTrained = false;
	dimension = dim; 
}

NNClassifier::~NNClassifier()
{
	if (isInitialized)
	{
        libNNTerminate();
	    mclTerminateApplication();
	}
}

void NNClassifier::init()
{

     mclmcrInitialize();

    if (!mclInitializeApplication(NULL,0)) 
    {
        std::cerr << "could not initialize the application properly"
                   << std::endl;
    	return; 
    }


    if( !libNNInitialize() )
    {
        std::cerr << "could not initialize the library properly"
                   << std::endl;
	return; 
    }

	isInitialized = true; 


}

void NNClassifier::train(list<NNData>& l)
{
	if (! isInitialized)
		return; 


	try
	{
		double* XD = new double[l.size() * dimension]; 
		double* YD = new double[l.size()]; 

		int ind =0;

		for(list<NNData>::iterator it= l.begin(); it != l.end(); it++)
		{
			for(int i=0; i < dimension; i++)
				XD[ind*dimension + i] = (*it).first[i]; 

			YD[ind] = (*it).second; 
			ind++;
		}
		
		mwArray X(l.size(), dimension,  mxDOUBLE_CLASS, mxREAL); 
		mwArray Y(l.size(), 1,  mxDOUBLE_CLASS, mxREAL); 

		X.SetData(XD, l.size()*dimension); 
		Y.SetData(YD, l.size()); 

		NNTrain(X, Y); 

		delete XD; 
		delete YD; 
		

	}catch(...)
	{
		printf("ERROR: in train NN\n"); 
	}

	isTrained = true; 

}

double NNClassifier::query(Observation o)
{
	double result =0; 

	if ( ! isInitialized || !isTrained)
		return 0; 


		mwArray X(1, dimension,  mxDOUBLE_CLASS, mxREAL); 
		mwArray Y(1, 1,  mxDOUBLE_CLASS, mxREAL); 

		X.SetData(o, dimension); 

		NNQuery(1, Y, X); 

		Y.GetData(&result, 1); 
		return result; 
}





